Java线程和OS线程 您所在的位置:网站首页 java 内核操作 Java线程和OS线程

Java线程和OS线程

2024-07-11 14:59| 来源: 网络整理| 查看: 265

Java线程和OS线程 操作系统实现线程有三种方式内核线程实现用户线程实现用户线程加轻量级进程混合实现Java线程的实现Java线程调度Java线程状态转换

操作系统实现线程有三种方式 内核线程实现用户线程实现用户线程加轻量级进程混合实现 内核线程实现

在这里插入图片描述 简要说明: 内核线程(Kernel-Level Thread简称KLT) 是直接由操作系统内核直接支持的线程,这种线程由内核完成线程切换,内核通过操纵调度器对线程进行调度,并负责将线程的任务映射到各个处理器上。

每个内核线程 可以视为内核的一个分身,这样操作系统就有能力处理多件事情,这种支持多线程的内核就叫做多线程内核;

程序一般不会直接操作内核线程,而是去使用内核线程的一种高级接口:轻量级进程(Light Weight Process,简称LWP),轻量级进程就是我们通常所讲的线程,每个轻量级进程都由一个内核线程支持,这种轻量级进程与内核线程1:1的关系称为一对一的线程模型。

优势: 由于有了内核线程的支持,每个轻量级进程都称为一个独立的调度单元,即使有一个轻量级进程在系统中阻塞了,也不会影响整个进程继续工作;

劣势: 由于基于内核线程实现,所以各种线程操作(创建,析构及同步等)都需要进行系统调用(系统调用代价相对较高,需要在用户态[User Mode]和内核态[Kernel Mode]来回切换);每个轻量级进程需要一个内核线程支持,因此需要消耗一定的内核资源(如内核线程的栈空间),因此一个系统支持轻量级进程的数量是有限的;

用户线程实现

在这里插入图片描述

用户线程 1、广义上来讲,任何非内核线程都可以认为是用户线程(User Thread,简称UT); 2、狭义上来讲,完全建立在用户空间的线程库上,系统内核不能感知线程存在的实现;

特点 1、用户线程的创建、同步、销毁和调度完全在用户态中完成,不需要内核的帮助,这种线程不需要切换到内核态,操作可以非常快速且低消耗;支持更大的线程数量;这种进程与用户线程之间1:N的关系称为一对多的线程模型; 2、用户线程的优势就是不需要系统内核支援,劣势就是没有内核支持,所有的线程操作(如线程的创建、切换和调度等)都需要用户程序自己处理。

用户线程加轻量级进程混合实现

在这里插入图片描述 用户线程+轻量级进程特点:

用户线程的创建、析构、切换等操作很廉价;支持大规模的用户线程并发;操作系统提供的轻量级进程作为用户线程和内核线程之间的桥梁,提供线程调度功能及处理器映射;用户线程的系统调用通过轻量级进程完成,降低了整个进程完全被阻塞的风险;这种用户线程和轻量级进程的数量比不定,即N:M的关系,称为多对多的线程模型 Java线程的实现

Java线程如何实现并不受Java虚拟机规范约束,这是一个与具体虚拟机相关的画图。Java线程在早期的Classic虚拟机上(JDK1.2以前),是基于一种被称为“绿色线程”(Green Threads)的用户线程实现的,但从JDK1.3起,“主流”平台上的“主流”商用Java虚拟机的线程模型普遍都被替换为基于操作系统原生线程模型来实现,即采用1:1的线程模型。

操作系统支持怎样的线程模型,在很大程度想会影响上面的Java虚拟机的线程是怎么样映射的,这一点咋不同的平台上很难达成一致,因此《Java虚拟机规范》中才不去限定Java线程需要使用哪种线程模型来实现。

Java线程调度

线程调度是指系统为线程分配处理使用权的过程,调度主要方式有两种,分别是协同式(Cooperative Threads-Scheduling)线程调度 和 抢占式(Preemptive Threads-Scheduling)线程调度。

协同式线程调度: 线程的执行时间由线程本身来控制,线程把自己的工作执行完了之后,要主动通知系统切换到另外一个线程上去。

优点: 实现简单,切换操作对线程自己是可知的,所以一般没有什么线程同步问题。缺点: 线程执行时间不可控制,甚至如果一个线程的代码编写有问题,一直不告知系统进行线程切换,那么程序就会一直阻塞在那里。

抢占式线程调度: 每个线程将由系统来分配执行时间,线程的切换不由线程本身来决定。

优点: 可以主动让出执行时间(例如Java的Thread::yield()方法),并且线程的执行时间是系统可控的,也不会有一个线程导致整个系统阻塞的问题。缺点: 无法主动获取执行时间。

Java使用的就是抢占式线程调度,虽然这种方式的线程调度是系统自己的完成的,但是我们可以给操作系统一些建议,就是通过设置线程优先级来实现。Java语言一共设置了10个级别的线程优先级。在两个线程同时处于Ready状态时,优先级越高的线程越容易被系统选择执行。

Java线程状态转换

Java语言定义了6种线程状态,在任意一个时间点钟,一个线程只能有且只有其中的一种状态,并且可以通过特定的方法在不同状态之间切换。

新建(New): 创建后尚未启动的线程处于这种状态。

运行(Runnable): 包括操作系统线程状态中的Running和Ready,也就是处理此状态的线程有可能正在执行,也有可能正在等待着操作系统为它分配执行时间。

无限期等待(Waiting): 处于这种状态的线程不会被分配处理器执行时间,它们要等待被其他线程显示唤醒。以下方法会让线程陷入无限期等待状态:

没有设置Timeout参数的Object::wait()方法;没有设置Timeout参数的Thread::join()方法;LockSupport::park()方法。

限期等待(Timed Waiting): 处于这种状态的线程也不会被分配处理器执行时间,不过无须等待被其他线程显式唤醒,在一定时间之后它们会由系统自动唤醒。以下方法会让线程进入限期等待状态:

Thread::sleep()方法;设置了Timeout参数的Object::wait()方法;设置了Timeout参数的Thread::join()方法;LockSupport::parkNanos()方法;LockSupport::parkUntil()方法;

阻塞(Blocked): 线程被阻塞了,“阻塞状态”与“等待状态”的区别是“阻塞状态”在等待着获取到一个排他锁,这个事件将在另外一个线程放弃这个锁的时候发生;而“等待状态”则是在等待一段时间 ,或者唤醒动作发生。在程序进入同步区域的时候,线程将进入这种状态。

结束(Terminated): 已终止线程的线程状态,线程已经结束执行。

这6种状态在遇到特定事件发生的时候将会互相转换,他们的转换关系如下图: 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有